package models

import (
	"backend/constants/usertype"
	"encoding/json"
	"github.com/beego/beego/v2/client/orm"
	"github.com/beego/beego/v2/core/logs"
	"time"
)

type FileUser struct {
	Id         int64     `json:"id,omitempty"`
	Username   string    `json:"username,omitempty"`
	Password   string    `json:"password,omitempty"`
	Type       string    `json:"type,omitempty"`
	Access     string    `json:"access,omitempty"`
	Enable     int       `json:"enable,omitempty"`
	CreateTime time.Time `json:"create_time"`
	UpdateTime time.Time `json:"update_time"`
}

func (t *FileUser) TableName() string {
	return "file_user"
}

func init() {
	orm.RegisterModel(new(FileUser))
}


// IsCurrentUser
// 判断用户是否存在
func IsCurrentUser(username string,password string)(bool,*FileUser){
	o := orm.NewOrm()
	qs := o.QueryTable(new(FileUser))
	sql := qs.Filter("username",username).Filter("password",password).Filter("enable",1)
	isExist := sql.Exist()
	member := &FileUser{}
	if isExist{
		_ = sql.One(member)
	}
	return isExist,member
}

// IsExistUser
// 判断用户是否存在
func IsExistUser(username string,password string)(bool,*FileUser){
	o := orm.NewOrm()
	qs := o.QueryTable(new(FileUser))
	sql := qs.Filter("username",username).Filter("password",password)
	isExist := sql.Exist()
	member := &FileUser{}
	if isExist{
		_ = sql.One(member)
	}
	return isExist,member
}

func GetUserAccessByUid(username string)map[string]interface{}{
	o := orm.NewOrm()
	qs := o.QueryTable(new(FileUser))
	sql := qs.Filter("username",username)
	isExist := sql.Exist()
	member := &FileUser{}
	defaultAccess := make(map[string]interface{})
	defaultAccess["list"] = false
	defaultAccess["read"] = false
	defaultAccess["write"] = false
	defaultAccess["rename"] = false
	defaultAccess["copy"] = false
	defaultAccess["create"] = false
	defaultAccess["remove"] = false
	if isExist{
		err := sql.One(member)
		if err!=nil{
			logs.Error(err.Error())
			return defaultAccess
		}else{
			return GetUserAccess(member)
		}
	}else{
		return defaultAccess
	}
}

func GetUserAccess(v *FileUser)map[string]interface{}{
	data := GetUserData(v)
	return data["access"].(map[string]interface{})
}


// GetUserData
// 获取用户数据
func GetUserData(v *FileUser)map[string]interface{}{
	access := make(map[string]interface{})
	data := make(map[string]interface{})
	defaultAccess := make(map[string]interface{})
	defaultAccess["list"] = true
	defaultAccess["read"] = true
	defaultAccess["write"] = true
	defaultAccess["rename"] = true
	defaultAccess["copy"] = true
	defaultAccess["create"] = true
	defaultAccess["remove"] = true
	if v.Access == ""{
		access = defaultAccess
	}else{
		err := json.Unmarshal([]byte(v.Access), &access)
		if err != nil {
			access = defaultAccess
		}
	}
	types := make(map[string]interface{})
	types[usertype.ADMIN] = "超级管理员"
	types[usertype.MANAGER] = "管理员"
	types[usertype.GUEST] = "普通用户"
	data["id"] = v.Id
	data["name"] = v.Username
	data["access"] = access
	data["usertype"] = v.Type
	data["type"] = types[v.Type]
	return data
}


func GetUserList(page int64,limit int64)(int64,interface{}){
	var users []FileUser
	o := orm.NewOrm()
	qs := o.QueryTable(new(FileUser))
	list := make([]interface{},0,limit)
	offset := (page-1)*limit
	count, err := qs.Count()
	if err != nil {
		return count,list
	}else{
		_, err := qs.Limit(limit,offset).All(&users)
		if err != nil {
			return 0, list
		}else{
			for _,v := range users{
				list = append(list,GetUserData(&v))
			}
		}
		return count,list
	}
}


func ChangeUserAccess(id int64,accessType string,accessValue bool)bool{
	var user FileUser
	o := orm.NewOrm()
	qs := o.QueryTable(new(FileUser)).Filter("id",id)
	err := qs.One(&user)
	if err != nil {
		logs.Error(err.Error())
		return false
	}else{
		data := GetUserData(&user)
		access := data["access"].(map[string]interface{})
		access[accessType] = accessValue
		marshal, err := json.Marshal(access)
		if err != nil {
			logs.Error(err.Error())
			return false
		}else{
			value := string(marshal)
			_, err := qs.Update(orm.Params{
				"access":      value,
				"update_time": time.Now(),
			})
			if err != nil {
				logs.Error(err.Error())
				return false
			}else{
				return true
			}
		}
	}
}


func GetUserIdByUsername(username string)int64{
	var user FileUser
	o := orm.NewOrm()
	qs := o.QueryTable(new(FileUser)).Filter("username",username)
	err := qs.One(&user)
	if err != nil {
		logs.Error(err.Error())
		return 0
	}else{
		return user.Id
	}
}

func IsExistId(id int64)bool{
	o := orm.NewOrm()
	qs := o.QueryTable(new(FileUser)).Filter("id",id)
	return qs.Exist()
}

func DeleteUser(id int64)bool{
	o := orm.NewOrm()
	qs := o.QueryTable(new(FileUser)).Filter("id",id)
	_, err := qs.Delete()
	if err != nil {
		logs.Error(err.Error())
		return false
	}else{
		return true
	}
}

func ChangeUserPassword(id int64,password string)bool{
	o := orm.NewOrm()
	qs := o.QueryTable(new(FileUser)).Filter("id",id)
	_, err := qs.Update(orm.Params{
		"password": password,
	})
	if err != nil {
		return false
	}else{
		return true
	}
}

func IsExistUsername(username string)bool{
	o := orm.NewOrm()
	return o.QueryTable(new(FileUser)).Filter("username",username).Exist()
}

func InsertUser(username string,password string,access string,userType string)bool{
	user := FileUser{
		Username:   username,
		Password:   password,
		Type: userType,
		Access:     access,
		Enable:     1,
		CreateTime: time.Now(),
		UpdateTime: time.Now(),
	}
	o := orm.NewOrm()
	_, err := o.Insert(&user)
	if err != nil {
		logs.Error(err.Error())
		return false
	}else{
		return true
	}
}


func GetUserType(username string)string{
	var user FileUser
	o := orm.NewOrm()
	qs := o.QueryTable(new(FileUser)).Filter("username",username)
	err := qs.One(&user)
	if err != nil {
		logs.Error(err.Error())
		return usertype.GUEST
	}else{
		return user.Type
	}
}